package com.xuetang9.controller.sn.interceptor;

import com.xuetang9.BO.RedisDO;
import com.xuetang9.utils.LoggerUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * @类: LoginInterceptor
 * @描述: 用户登录权限拦截器
 * @date: 2020/5/25
 * @author: Admin
 * @ver 1.0.0
 * @since JDK 1.8
 */
@CrossOrigin
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 另外，规范要求，对那些可能对服务器数据产生副作用的 HTTP 请求方法（特别是 GET 以外的 HTTP 请求，或者搭配某些 MIME 类型的 POST 请求），
     *  浏览器必须首先使用 OPTIONS 方法发起一个预检请求（preflight request），
     *  从而获知服务端是否允许该跨域请求。服务器确认允许之后，才发起实际的 HTTP 请求。
     */
    private static final String OPTIONS = "OPTIONS";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        LoggerUtils.debug("进行拦截。。。。");

        if (OPTIONS.equals(request.getMethod())){
            //跨域资源共享标准新增了一组 HTTP 首部字段，允许服务器声明哪些源站有权限访问哪些资源。
            // 另外，规范要求，对那些可能对服务器数据产生副作用的 HTTP 请求方法（特别是 GET 以外的 HTTP 请求，或者搭配某些 MIME 类型的 POST 请求），
            // 浏览器必须首先使用 OPTIONS 方法发起一个预检请求（preflight request），
            // 从而获知服务端是否允许该跨域请求。服务器确认允许之后，才发起实际的 HTTP 请求。
            // 在预检请求的返回中，服务器端也可以通知客户端，是否需要携带身份凭证（包括 Cookies 和 HTTP 认证相关数据）。
            // 参考：https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        //打印请求地址
        LoggerUtils.info("请求地址为：{}",request.getRequestURI());

        //获取token
        String token = request.getHeader("token");

        //根据获取token
        if (token == null || token.isEmpty()) {
            //不存在，设置错误状态码
            response.setStatus(401);
        } else {
            //存在
            //判断是否过期
            if (RedisDO.isUserExpired(token)) {
                //过期，设置错误状态码
                response.setStatus(401);
            } else {
                //更新token时间
                RedisDO.recordUser(token,new Date());
                return true;
            }
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
